<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns="http://www.w3.org/2000/svg"
	xmlns:svg="http://www.w3.org/2000/svg"
	xmlns:html="http://www.w3.org/1999/xhtml"
	xmlns:doc="livcos.org/ns/doc"
	xmlns:dg="livcos.org/ns/doc/diagram"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:f="livcos.org/ns/xslt/function"
	xmlns:m="livcos.org/ns/xslt/function/math"
	exclude-result-prefixes="doc html dg f xs svg xlink m">
	
	<xsl:import href="../../../common/extensions.xsl"/>

	<xsl:param name="incl-editor" select="'1'"/>
	
	<xsl:variable name="tmpl_path"
		select="'/livcos.org/type/template/livcos.org/ns/doc/diagram/path#template_1'"/>
	<xsl:variable name="tmpl_line"
		select="'/livcos.org/type/template/livcos.org/ns/doc/diagram/line#template_1'"/>
	
	<xsl:template match="dg:diagram">
		<html:div id="{@id}">
			<xsl:choose>
				<xsl:when test="@align = 'left'">
					<xsl:attribute name="style">float: <xsl:value-of select="@align"/></xsl:attribute>
				</xsl:when>
				<xsl:when test="@align = 'right'">
					<xsl:attribute name="style">float: <xsl:value-of select="@align"/></xsl:attribute>
				</xsl:when>
				<xsl:when test="@align = 'center'">
					<xsl:attribute name="style">text-align: <xsl:value-of select="@align"/></xsl:attribute>
				</xsl:when>
			</xsl:choose>
			<xsl:apply-templates select="." mode="svg"/>
			<xsl:if test="normalize-space(doc:note) != ''">
				<html:div class="image_note">
					<html:span class="inlineEdit" title="note">
						<xsl:value-of select="doc:note"/>
					</html:span>
				</html:div>
			</xsl:if>
		</html:div>
	</xsl:template>
	
	<xsl:template match="dg:diagram" mode="svg">
		<xsl:variable name="prep">
			<xsl:variable name="tmp">
				<xsl:apply-templates select="dg:*" mode="dg_measure"/>
			</xsl:variable>
			<xsl:apply-templates select="$tmp/*" mode="dg_connect"/>
		</xsl:variable>
		<xsl:variable name="vpMax" select="max($prep/*/@viewPortMaxX), max($prep/*/@viewPortMaxY)"/>
		<xsl:variable name="vpMin" select="min($prep/*/@viewPortMinX), min($prep/*/@viewPortMinY)"/>
		<xsl:variable name="vp" select="f:subV($vpMax, $vpMin)"/>
		<svg version="1.1" width="{$vp[1] + 4}" height="{$vp[2] + 4}">
			<defs>
				<marker id="arrow_1" viewBox="0 0 16 10" refX="0" refY="5" markerUnits="strokeWidth"
					markerWidth="10" markerHeight="8" orient="auto">
					<path d="M 0 5 L 16 0 L 16 10 z"/>
				</marker>
				<marker id="arrow_2" viewBox="0 0 16 10" refX="16" refY="5" markerUnits="strokeWidth"
					markerWidth="10" markerHeight="8" orient="auto">
					<path d="M 0 0 L 16 5 L 0 10 z"/>
				</marker>
				<marker id="arrow_3" viewBox="0 0 10 10" refX="10" refY="5" markerUnits="strokeWidth"
					markerWidth="10" markerHeight="10" orient="auto">
					<path d="M 0,0 L 10,5 0,10 z" fill="white" stroke="black" stroke-width="1"/>
				</marker>
				<marker id="arrow_end_open" viewBox="0 0 16 10" refX="16" refY="5" markerUnits="strokeWidth"
					markerWidth="10" markerHeight="8" orient="auto">
					<path d="M 0,0 L 16,5 0,10" fill="none" stroke="black" stroke-width="1"/>
				</marker>
				<marker id="bullet" viewBox="0 0 8 8" refX="0" refY="4" markerUnits="strokeWidth"
					markerWidth="4" markerHeight="4" orient="auto">
					<circle cx="4" cy="4" r="4" stroke="none"/>
				</marker>
			</defs>
			<g style="font-size: 16px;" transform="translate({f:printV(f:subV((2,2), $vpMin))})">
				<xsl:apply-templates select="$prep/*"/>
			</g>
		</svg>
	</xsl:template>
	
	<xsl:template match="dg:box">
		<xsl:variable name="w" select="@width div 2"/>
		<xsl:variable name="h" select="@height div 2"/>
		<xsl:variable name="p" select="f:castV(@pos)"/>
		<g id="{@id}" class="box" fill="#44AAAA">
			<xsl:attribute name="transform">
				<xsl:text>translate(</xsl:text>
				<xsl:value-of select="f:subV($p, ($w, $h))"/>
				<xsl:text>)</xsl:text>
				<xsl:if test="@angle">
					<xsl:text>rotate(</xsl:text>
					<xsl:value-of select="@angle"/>
					<xsl:text> </xsl:text>
					<xsl:value-of select="$w"/>
					<xsl:text> </xsl:text>
					<xsl:value-of select="$h"/>
					<xsl:text>)</xsl:text>
				</xsl:if>
			</xsl:attribute>
			<circle cx="{$p[1]}" cy="{$p[2]}" r="0" fill="none"/>
			<xsl:choose>
				<xsl:when test="svg:*">
					<xsl:copy-of select="svg:*" copy-namespaces="no"/>
				</xsl:when>
				<xsl:otherwise>
					<a xlink:href="{@ref}">
						<rect stroke="black" x="0" y="0" width="{@width}" height="{@height}" rx="4" ry="4"/>
						<text x="{$w}" y="{$h + 6}" fill="white" style="text-anchor: middle">
							<xsl:value-of select="."/>
						</text>
					</a>
				</xsl:otherwise>
			</xsl:choose>
		</g>
	</xsl:template>
	
	<xsl:template match="dg:circle">
		<g id="{@id}" class="circle" fill="#44AAAA">
			<xsl:attribute name="transform">
				<xsl:text>translate(</xsl:text>
				<xsl:value-of select="@pos"/>
				<xsl:text>)</xsl:text>
			</xsl:attribute>
			<a xlink:href="{@ref}">
				<circle stroke="black" r="{@r}"/>
				<text x="0" y="6" fill="white" style="text-anchor: middle">
					<xsl:value-of select="."/>
				</text>
			</a>
		</g>
	</xsl:template>
	
	<xsl:template match="dg:connect">
		<xsl:variable name="path_" select="../dg:path[@ref = current()/@id]"/>
		<xsl:variable name="path">
			<xsl:apply-templates select="dg:*" mode="path"/>
		</xsl:variable>
		<xsl:variable name="g">
		</xsl:variable>
		<g class="path">
			<xsl:copy-of select="@id"/>
			<xsl:if test="$incl-editor = '1'">
				<path d="M {@startV}{$path} {@endV}" fill="none" stroke="#FFFFFF" stroke-width="5"/>
			</xsl:if>
			<path d="M {@startV}{$path} {@endV}" fill="none" stroke="#556677" stroke-width="1">
				<xsl:if test="@marker-start">
					<xsl:attribute name="marker-start">url(#<xsl:value-of select="@marker-start"/>)</xsl:attribute>
				</xsl:if>
				<xsl:if test="@marker-end">
					<xsl:attribute name="marker-end">url(#<xsl:value-of select="@marker-end"/>)</xsl:attribute>
				</xsl:if>
			</path>
			<xsl:apply-templates select="dg:*"/>
		</g>
	</xsl:template>
	
	<xsl:template match="dg:text" mode="path">
	</xsl:template>
	
	<xsl:template match="dg:line" mode="path">
		<xsl:if test="@to">
			<xsl:text> L</xsl:text>
			<xsl:value-of select="@to"/>
		</xsl:if>
	</xsl:template>
	
	<xsl:template match="dg:connect/dg:line">
		<xsl:variable name="p" as="xs:double*">
			<xsl:choose>
				<xsl:when test="@to">
					<xsl:copy-of select="f:castV(@to)"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:variable name="ps" select="preceding-sibling::*/@to"/>
					<xsl:variable name="prev" select="f:castV(if ($ps) then $ps[1] else ../@startV)"/>
					<xsl:variable name="fs" select="following-sibling::*/@to"/>
					<xsl:variable name="next" select="f:castV(if ($fs) then $fs[1] else ../@endV)"/>
					<xsl:variable name="diff" select="f:subV($next, $prev)"/>
					<xsl:copy-of select="f:addV($prev, ($diff[1] div 2, $diff[2] div 2))"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="id">
			<xsl:choose>
				<xsl:when test="@id">
					<xsl:value-of select="@id"/>
				</xsl:when>
				<xsl:when test="@tmpl">
					<xsl:value-of select="@tmpl"/>:<xsl:value-of select="@tmpl-args"/>
					<xsl:if test="not(@tmpl-args)"><xsl:value-of select="f:printV($p)"/></xsl:if>
				</xsl:when>
				<xsl:otherwise>
					<xsl:text>/livcos.org/type/template/livcos.org/ns/doc/diagram/line#template_1:</xsl:text>
					<xsl:value-of select="position()"/>:<xsl:value-of select="f:printV($p)"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<circle id="{$id}" class="lineTo" cx="{$p[1]}" cy="{$p[2]}" r="3" fill="none"/>
	</xsl:template>
	
	<xsl:template match="dg:connect/dg:text">
		<xsl:variable name="eA" select="@anchor = 'end'"/>
		<xsl:variable name="s" select="f:castV(if ($eA) then ../@endV else ../@startV)"/>
		<xsl:variable name="e" select="f:castV(if ($eA) then ../@startV else ../@endV)"/>
		<xsl:variable name="p" as="xs:double*">
			<xsl:choose>
				<xsl:when test="../dg:line | ../dg:curve">
					<xsl:variable name="ps" select="../*/@to"/>
					<xsl:copy-of select="f:castV(if ($eA) then $ps[last()] else $ps[1])"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:copy-of select="$e"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="v" select="f:subV($p, $s)"/>
		<xsl:variable name="xy" select="$v[1] >= $v[2]"/>
		<xsl:variable name="yx" select="$v[2] > -$v[1]"/>
		<xsl:variable name="r" select="if (@anchor = 'end') then @side != 'right' else @side = 'right'"/>
		<xsl:variable name="lr" select="($xy and $r) or ($yx and not($r))"/>
		<xsl:variable name="t" select="($xy and not($r)) or (not($yx) and $r)"/>
		<xsl:variable name="anchor">
			<xsl:choose>
				<xsl:when test="@align = 'left'">start</xsl:when>
				<xsl:when test="@align = 'right'">end</xsl:when>
				<xsl:when test="@align = 'center'">middle</xsl:when>
				<xsl:when test="$lr">start</xsl:when>
				<xsl:otherwise>end</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="y" select="if ($t) then -4 else 10"/>
		<text id="{@id}" x="0" y="{$y}" fill="black" style="text-anchor: {$anchor}; font-size: 10px">
			<xsl:attribute name="transform">
				<xsl:text>translate(</xsl:text>
				<xsl:choose>
					<xsl:when test="not(@pos)">
						<xsl:variable name="p1" select="if ($lr) then 3 else -3"/>
						<xsl:variable name="p2" select="if ($t) then -1 else 1"/>
						<xsl:value-of select="f:printV(f:addV($s, ($p1, $p2)))"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:variable name="p" select="f:castV(@pos)"/>
						<!-- transform the coordinate system
						<xsl:variable name="p1" select="if ($lr) then $p[1] else -$p[1]"/>
						<xsl:variable name="p2" select="if ($t) then -$p[2] else $p[2]"/>
						<xsl:value-of select="f:printV(f:addV(f:castV(../@start), ($p1, $p2)))"/>
						-->
						<xsl:value-of select="f:printV(f:addV($s, $p))"/>
					</xsl:otherwise>
				</xsl:choose>
				<xsl:text>)</xsl:text>
			</xsl:attribute>
			<xsl:value-of select="."/>
		</text>
	</xsl:template>
	
	<xsl:template match="dg:*">
	</xsl:template>
	
	<xsl:template match="dg:*" mode="dg_measure">
		<xsl:copy-of select="."/>
	</xsl:template>
	
	<xsl:template match="dg:path" mode="dg_measure">
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:variable name="coords">
				<xsl:for-each select="tokenize(string-join(@path, ' '), ' ')">
					<xsl:variable name="c" select="tokenize(., ',')"/>
					<c x="{$c[1]}" y="{$c[2]}"/>
				</xsl:for-each>
				<xsl:for-each select="dg:*/@to">
					<xsl:variable name="c" select="tokenize(., ',')"/>
					<c x="{$c[1]}" y="{$c[2]}"/>
				</xsl:for-each>
			</xsl:variable>
			<xsl:if test="$coords/*">
				<xsl:attribute name="viewPortMaxX">
					<xsl:value-of select="max($coords/*/@x)"/>
				</xsl:attribute>
				<xsl:attribute name="viewPortMaxY">
					<xsl:value-of select="max($coords/*/@y)"/>
				</xsl:attribute>
				<xsl:attribute name="viewPortMinX">
					<xsl:value-of select="min($coords/*/@x)"/>
				</xsl:attribute>
				<xsl:attribute name="viewPortMinY">
					<xsl:value-of select="min($coords/*/@y)"/>
				</xsl:attribute>
			</xsl:if>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:box" mode="dg_measure">
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:variable name="id" select="substring(@ref, 2)"/>
			<xsl:variable name="label">
				<xsl:apply-templates select="//*[@id = $id]" mode="dgrm_label"/>
			</xsl:variable>
			<xsl:variable name="w" select="if (@width) then @width else string-length($label) * 10 + 20"/>
			<xsl:variable name="h" select="if (@height) then @height else 50"/>
			<xsl:variable name="a" select="if (@angle) then @angle else 0"/>
			<xsl:variable name="c" select="f:castV(@pos)"/>
			<xsl:variable name="m" select="f:rotateV(($w div 2, $h div 2), $a)"/>
			<xsl:variable name="viewPortMaxV" select="f:addV($c, $m)"/>
			<xsl:attribute name="viewPortMaxX">
				<xsl:value-of select="$viewPortMaxV[1]"/>
			</xsl:attribute>
			<xsl:attribute name="viewPortMaxY">
				<xsl:value-of select="$viewPortMaxV[2]"/>
			</xsl:attribute>
			<xsl:variable name="viewPortMinV" select="f:subV($c, $m)"/>
			<xsl:attribute name="viewPortMinX">
				<xsl:value-of select="$viewPortMinV[1]"/>
			</xsl:attribute>
			<xsl:attribute name="viewPortMinY">
				<xsl:value-of select="$viewPortMinV[2]"/>
			</xsl:attribute>
			<xsl:attribute name="width">
				<xsl:value-of select="$w"/>
			</xsl:attribute>
			<xsl:attribute name="height">
				<xsl:value-of select="$h"/>
			</xsl:attribute>
			<xsl:if test="not(@angle)">
				<xsl:attribute name="angle">0</xsl:attribute>
			</xsl:if>
			<xsl:choose>
				<xsl:when test="* | text()">
					<xsl:copy-of select="* | text()"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$label"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:circle" mode="dg_measure">
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:variable name="id" select="substring(@ref, 2)"/>
			<xsl:variable name="label">
				<xsl:apply-templates select="//*[@id = $id]" mode="dgrm_label"/>
			</xsl:variable>
			<xsl:variable name="r" select="string-length($label) * 5 + 6"/>
			<xsl:variable name="c" select="f:castV(@pos)"/>
			<xsl:variable name="m" select="$r, $r"/>
			<xsl:variable name="viewPortMaxV" select="f:addV($c, $m)"/>
			<xsl:attribute name="viewPortMaxX">
				<xsl:value-of select="$viewPortMaxV[1]"/>
			</xsl:attribute>
			<xsl:attribute name="viewPortMaxY">
				<xsl:value-of select="$viewPortMaxV[2]"/>
			</xsl:attribute>
			<xsl:variable name="viewPortMinV" select="f:subV($c, $m)"/>
			<xsl:attribute name="viewPortMinX">
				<xsl:value-of select="$viewPortMinV[1]"/>
			</xsl:attribute>
			<xsl:attribute name="viewPortMinY">
				<xsl:value-of select="$viewPortMinV[2]"/>
			</xsl:attribute>
			<xsl:attribute name="r">
				<xsl:value-of select="$r"/>
			</xsl:attribute>
			<xsl:value-of select="$label"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:function name="f:centerV" as="xs:double*">
		<xsl:param name="box" as="element()"/>
		<xsl:apply-templates select="$box" mode="centerV"/>
	</xsl:function>
	
	<xsl:function name="f:hullV" as="xs:double*">
		<xsl:param name="box" as="element()"/>
		<xsl:param name="p" as="xs:double*"/>
		<xsl:apply-templates select="$box" mode="hullV">
			<xsl:with-param name="p" select="$p"/>
		</xsl:apply-templates>
	</xsl:function>
	
	<xsl:template match="dg:box" mode="centerV" as="xs:double*">
		<xsl:copy-of select="f:castV(@pos)"/>
	</xsl:template>
	
	<xsl:template match="dg:box" mode="hullV" as="xs:double*">
		<xsl:param name="p"/>
		<xsl:variable name="w" select="@width div 2"/>
		<xsl:variable name="h" select="@height div 2"/>
		<xsl:variable name="c" select="f:castV(@pos)"/>
		<xsl:variable name="a" select="f:rotateV(f:subV($p, $c), -@angle)"/>
		<xsl:variable name="r" as="xs:double*">
			<xsl:value-of select="if (abs($a[1]) > $w) then $w * abs($a[1]) div $a[1] else $a[1]"/>
			<xsl:value-of select="if (abs($a[2]) > $h) then $h * abs($a[2]) div $a[2] else $a[2]"/>
		</xsl:variable>
		<xsl:copy-of select="f:addV($c, f:rotateV($r, @angle))"/>
	</xsl:template>
	
	<xsl:template match="dg:circle" mode="centerV" as="xs:double*">
		<xsl:copy-of select="f:castV(@pos)"/>
	</xsl:template>
	
	<xsl:template match="dg:circle" mode="hullV" as="xs:double*">
		<xsl:param name="p"/>
		<xsl:variable name="c" select="f:castV(@pos)"/>
		<xsl:variable name="a" select="f:subV($p, $c)"/>
		<xsl:variable name="r" select="@r div f:lenV($a)"/>
		<xsl:copy-of select="$c[1] + $a[1] * $r, $c[2] + $a[2] * $r"/>
	</xsl:template>
	
	<xsl:template match="dg:*" mode="dg_connect">
		<xsl:copy-of select="."/>
	</xsl:template>
	
	<xsl:template match="dg:connect" mode="dg_connect">
		<xsl:variable name="sB" select="../*[@id = current()/@start]"/>
		<xsl:variable name="eB" select="../*[@id = current()/@end]"/>
		<xsl:variable name="s1" select="f:hullV($sB, f:centerV($eB))"/>
		<xsl:variable name="e1" select="f:hullV($eB, $s1)"/>
		<xsl:variable name="e2" select="f:hullV($eB, f:centerV($sB))"/>
		<xsl:variable name="s2" select="f:hullV($sB, $e2)"/>
		<xsl:variable name="e" select="f:hullV($eB, f:mulV(f:addV($s1, $s2), 0.5))"/>
		<xsl:variable name="s" select="f:hullV($sB, f:mulV(f:addV($e1, $e2), 0.5))"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:copy-of select="*"/>
			<xsl:variable name="p" select="f:printV(f:mulV(f:addV($s, $e), 0.5))"/>
			<xsl:variable name="tmpl-args"
				select="concat(@tmpl-args, ':', $p)"/>
			<dg:line to="{$p}" tmpl="{$tmpl_path}" tmpl-args="{$tmpl-args}"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:connect[@start = @end]" mode="dg_connect">
		<xsl:variable name="b" select="../*[@id = current()/@start]"/>
		<xsl:variable name="s0" select="f:hullV($b, f:addV(f:centerV($b), (0, 10000000)))"/>
		<xsl:variable name="num"
			select="count(preceding-sibling::dg:connect[(@start = current()/@start) and (@start = @end)])"/>
		<xsl:variable name="s" select="f:addV($s0, ($num * 20, 0))"/>
		<xsl:variable name="p1" select="f:addV($s, (0, 10))"/>
		<xsl:variable name="p2" select="f:addV($s, (15, 10))"/>
		<xsl:variable name="e" select="f:hullV($b, $p2)"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:attribute name="viewPortMaxX"><xsl:value-of select="$p2[1]"/></xsl:attribute>
			<xsl:attribute name="viewPortMaxY"><xsl:value-of select="$p2[2]"/></xsl:attribute>
			<xsl:copy-of select="*"/>
			<xsl:variable name="tmpl-args"
				select="concat(@tmpl-args, ':', f:printV($p1), ':', f:printV($p2))"/>
			<dg:line tmpl="{$tmpl_path}" tmpl-args="{$tmpl-args}" to="{f:printV($p1)}"/>
			<dg:line tmpl="{$tmpl_path}" tmpl-args="{$tmpl-args}" to="{f:printV($p2)}"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:connect[@path]" mode="dg_connect" priority="2">
		<xsl:variable name="sB" select="../*[@id = current()/@start]"/>
		<xsl:variable name="eB" select="../*[@id = current()/@end]"/>
		<xsl:variable name="ps" select="tokenize(@path, ' ')"/>
		<xsl:variable name="s" select="f:hullV($sB, f:castV($ps[1]))"/>
		<xsl:variable name="e" select="f:hullV($eB, f:castV($ps[last()]))"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:copy-of select="*"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:connect[dg:*/@to]" mode="dg_connect" priority="2">
		<xsl:variable name="sB" select="../*[@id = current()/@start]"/>
		<xsl:variable name="eB" select="../*[@id = current()/@end]"/>
		<xsl:variable name="s" select="f:hullV($sB, f:castV((dg:*/@to)[1]))"/>
		<xsl:variable name="e" select="f:hullV($eB, f:castV((dg:*/@to)[last()]))"/>
		<xsl:copy>
			<xsl:copy-of select="@*"/>
			<xsl:attribute name="startV"><xsl:value-of select="f:printV($s)"/></xsl:attribute>
			<xsl:attribute name="endV"><xsl:value-of select="f:printV($e)"/></xsl:attribute>
			<xsl:apply-templates select="*" mode="#current">
				<xsl:with-param name="startV" select="$s"/>
				<xsl:with-param name="endV" select="$e"/>
			</xsl:apply-templates>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="dg:line" mode="dg_connect">
		<xsl:param name="startV"/>
		<xsl:param name="endV"/>
		<xsl:variable name="t" select="f:castV(@to)"/>
		<xsl:if test="position() = 1">
			<xsl:variable name="p" select="f:printV(f:mulV(f:addV($startV, $t), 0.5))"/>
			<dg:line to="{$p}" tmpl="{$tmpl_line}" tmpl-args="{$p}"/>
		</xsl:if>
		<xsl:copy-of select="."/>
		<xsl:variable name="next" select="following-sibling::dg:line[1]"/>
		<xsl:variable name="e" select="if ($next) then f:castV($next/@to) else $endV"/>
		<xsl:variable name="p" select="f:printV(f:mulV(f:addV($t, $e), 0.5))"/>
		<dg:line to="{$p}" tmpl="{$tmpl_line}" tmpl-args="{$p}"/>
	</xsl:template>
	
	<xsl:template match="*" mode="dgrm_label">
		<xsl:value-of select="."/>
	</xsl:template>
	
	<xsl:template match="*[@name]" mode="dgrm_label">
		<xsl:value-of select="@name"/>
	</xsl:template>
	
	<xsl:template match="doc:chapter" mode="dgrm_label">
		<xsl:value-of select="doc:title"/>
	</xsl:template>
	
	<xsl:template match="doc:document" mode="dgrm_label">
		<xsl:value-of select="doc:head/doc:title"/>
	</xsl:template>
	
	<xsl:function name="f:castV" as="xs:double*">
		<xsl:param name="val"/>
		<xsl:for-each select="tokenize($val, '[, ]+')">
			<xsl:value-of select="."/>
		</xsl:for-each>
	</xsl:function>
	
	<xsl:function name="f:rotateV" as="xs:double*">
		<xsl:param name="v" as="xs:double*"/>
		<xsl:param name="degree" as="xs:double"/>
		<xsl:variable name="r" select="m:rad($degree)"/>
		<xsl:value-of select="$v[1] * m:cos($r) - $v[2] * m:sin($r)"/>
		<xsl:value-of select="$v[1] * m:sin($r) + $v[2] * m:cos($r)"/>
	</xsl:function>
	
	<xsl:function name="f:addV" as="xs:double*">
		<xsl:param name="v1" as="xs:double*"/>
		<xsl:param name="v2" as="xs:double*"/>
		<xsl:for-each select="$v1">
			<xsl:variable name="i" select="position()"/>
			<xsl:value-of select=". + $v2[$i]"/>
		</xsl:for-each>
	</xsl:function>
	
	<xsl:function name="f:subV" as="xs:double*">
		<xsl:param name="v1" as="xs:double*"/>
		<xsl:param name="v2" as="xs:double*"/>
		<xsl:for-each select="$v1">
			<xsl:variable name="i" select="position()"/>
			<xsl:value-of select=". - $v2[$i]"/>
		</xsl:for-each>
	</xsl:function>
	
	<xsl:function name="f:mulV" as="xs:double*">
		<xsl:param name="v" as="xs:double*"/>
		<xsl:param name="s" as="xs:double"/>
		<xsl:for-each select="$v">
			<xsl:value-of select=". * $s"/>
		</xsl:for-each>
	</xsl:function>
	
	<xsl:function name="f:lenV" as="xs:double">
		<xsl:param name="v" as="xs:double*"/>
		<xsl:value-of select="m:sqrt($v[1] * $v[1] + $v[2] * $v[2])"/>
	</xsl:function>
	
	<xsl:function name="f:printV" as="xs:string">
		<xsl:param name="v" as="xs:double*"/>
		<xsl:variable name="_retVal">
			<xsl:for-each select="$v">
				<xsl:if test="position() > 1">,</xsl:if>
				<xsl:value-of select="round(.)"/>
			</xsl:for-each>
		</xsl:variable>
		<xsl:value-of select="$_retVal"/>
	</xsl:function>
	
</xsl:stylesheet>